from HIT.metasearch import metasearch
from models import *
from HIT.peoplesearch import peoplesearch
from HIT.whois import whois, WhoisError

'''---------------------- Data triangulation methods and constants ----------------------'''

# Constant that determines the number of tags used by the data triangulator to search for other data through metasearch
DATA_TAG_COUNT = 10

# Function that creates a tag list of a webpage, uses metasearch to search for other data and returns the results
def data_triangulate(link):
    # Make taglist through WordCloudGenerator
    ##w = WordCloudGenerator(link)
    ##taglist = w.create_tag_list(DATA_TAG_COUNT)
    
    # Create query and use metasearch
    q = []
    #TODO Check if this works
    ##for (word, _) in taglist:
    ##    q.append(word)
    
    query = ' '.join(q)
    #print '--------------QUERY: ' + query
    dataresults = metasearch(query)
    return query, dataresults

# Function that stores the checked results of the data triangulation
def data_triangulate_store(links, reliability, additional_links = '', notes = ''):
    dtr = DataTriangulateResult(reliability = reliability, notes = notes)
    dtr.save()
    
    # Add additional links
    if len(additional_links):
        additional_links = additional_links.replace('\r','')
        additional_links = additional_links.split('\n')
        
        if len(additional_links):
            links = links + additional_links
    
    # Remove doubles
    links = list(set(links))
    
    # Make Link models
    for url in links:
        l = Link(link = url)
        l.save()
        dtr.links.add(l)
    
    return dtr

# Function that returns the stored data triangulation of a triangulation result
def data_triangulate_result(tr):
    if not tr.data_result:
        return None
    
    return {'links': tr.data_result.links.values_list("link", flat = True),
            'reliability': tr.data_result.reliability,
            'notes': tr.data_result.notes}




'''---------------------- Investigator triangulation methods and constants ----------------------'''

# Function that triangulates the information of a person
def investigator_triangulate(first_name, last_name, location = None, domain = None):
    p = None
    #if len(first_name) and len(last_name):

        #p = peoplesearch(first_name, last_name, location)

    whoisdata = ''

    if domain:
        try:
            whoisdata = whois(domain)
        except WhoisError, e:
            whoisdata = 'Could not get whois-information of %s because of the following error: %s' % (domain, str(e.value))
        except Exception:
            whoisdata = 'Could not get whois-information of %s because of an unknown error.' % domain
    return {'personlinks': p, 'whoisdata': whoisdata}

# Function that stores the data of an investigator triangulation
def investigator_triangulate_store(links, info, whoisdata, reliability, notes = ''):
    itr = InvestigatorTriangulateResult(additional_info = info, whois=whoisdata, reliability=reliability, notes=notes)
    itr.save()
    
    # add every link to result
    for url in links:
        l = Link(link = url)
        l.save()
        itr.links.add(l)
    
    return itr

# Function that returns the stored investigator triangulation of a triangulation result
def investigator_triangulate_result(tr):
    if not tr.investigator_result:
        return None
    
    return {'additional_info': tr.investigator_result.additional_info, 
            'whoisdata': tr.investigator_result.whois,
            'links': tr.investigator_result.links.values_list('link', flat = True),
            'reliability': tr.investigator_result.reliability,
            'notes': tr.investigator_result.notes}




'''---------------------- Theory triangulation methods and constants ----------------------'''

# Function implementing the theory triangulation
def theory_triangulate(link):
    # Use WordCloudGenerator to create a taglist and cloud of the page
    ##w = WordCloudGenerator(link)
    ##tags = w.create_tag_list()
    ##cloud = w.create_html_cloud(size=(900,900))
    
    return {'taglist': None, 'cloud': None}

# Function that stores the data of a theory triangulation
def theory_triangulate_store(taglist, reliability = None, notes = ''):
    ttr = TheoryTriangulateResult(reliability = reliability, notes = notes)
    ttr.save()
    if taglist is not None:    
        for (tag,count) in taglist:
            t = Tag(tag = tag, count = count, theory_result = ttr)
            t.save()
    
    return ttr

# Function that retrieves the result of a theory triangulation from the database
# @param tr: Triangulation Result, countains the theory triangulation result
# @requires: tr not is None
# @return: dict object with taglist([(unicode,int)]) and cloud (unicode)
def theory_triangulate_result(tr):
    if not tr.theory_result:
        return None
    
    taglist = tr.theory_result.tag_set.values_list('tag', 'count').order_by('-count')
    ##w = WordCloudGenerator(taglist, datatype='taglist')
    ##cloud = w.create_html_cloud(size=(900,900))
    
    return {'taglist': taglist,
            'cloud': None,
            'reliability': tr.theory_result.reliability,
            'notes': tr.theory_result.notes}




'''---------------------- Method triangulation methods and constants ----------------------'''

#Function that stores the selected methods in the database
#@param methods An array of id's representing selectable methods stored in the database
def method_triangulate_store(methods, reliability, notes = ''):
    mtr = MethodTriangulateResult(reliability = reliability, notes = notes)
    mtr.save()
    
    for m in methods:
        m_object = Method.objects.get(id = m)
        mtr.methods.add(m_object)
    
    return mtr

def method_triangulate_result(tr):
    if not tr.method_result:
        return None
    
    return {'methods': tr.method_result.methods.values_list('method', flat = True),
            'reliability': tr.method_result.reliability,
            'notes': tr.method_result.notes}







